package org.jeecg.common.util.oss;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

@Slf4j
public class StsOssTokenUtil {
    // 从环境变量中获取步骤1.1生成的RAM用户的访问密钥（AccessKey ID和AccessKey Secret）。
    private static String accessKeyId;
    private static String accessKeySecret;
    // STS服务接入点，例如sts.cn-hangzhou.aliyuncs.com。您可以通过公网或者VPC接入STS服务。
    private static String roleArn;
    // STS服务接入点，例如sts.cn-hangzhou.aliyuncs.com。您可以通过公网或者VPC接入STS服务。
    private static String endpoint;
    // 自定义角色会话名称，用来区分不同的令牌，例如可填写为SessionTest。
    private static String roleSessionName = "bigFileSession";
    // 临时访问凭证将获得角色拥有的所有权限。
    private static String policy = null;
    // 临时访问凭证的有效时间，单位为秒。最小值为900，最大值以当前角色设定的最大会话时间为准。当前角色最大会话时间取值范围为3600秒~43200秒，默认值为3600秒。
    // 在上传大文件或者其他较耗时的使用场景中，建议合理设置临时访问凭证的有效时间，确保在完成目标任务前无需反复调用STS服务以获取临时访问凭证。
    private static Long durationSeconds = 3600L;
    // 发起STS请求所在的地域。建议保留默认值，默认值为空字符串（""）。
    private static String regionId = "";

    public static String getEndpoint() {
        return endpoint;
    }

    public static void setEndpoint(String endpoint) {
        StsOssTokenUtil.endpoint = endpoint;
    }

    public static String getAccessKeyId() {
        return accessKeyId;
    }

    public static void setAccessKeyId(String accessKeyId) {
        StsOssTokenUtil.accessKeyId = accessKeyId;
    }

    public static String getAccessKeySecret() {
        return accessKeySecret;
    }

    public static void setAccessKeySecret(String accessKeySecret) {
        StsOssTokenUtil.accessKeySecret = accessKeySecret;
    }

    public static String getRoleArn() {
        return roleArn;
    }

    public static void setRoleArn(String roleArn) {
        StsOssTokenUtil.roleArn = roleArn;
    }

    public static Map<String, Object> getOssToken() {
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            // 添加endpoint。适用于Java SDK 3.12.0及以上版本。
            DefaultProfile.addEndpoint(regionId, "Sts", endpoint);
            // 添加endpoint。适用于Java SDK 3.12.0以下版本。
            // DefaultProfile.addEndpoint("",regionId, "Sts", endpoint);
            // 构造default profile。
            IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
            // 构造client。
            DefaultAcsClient client = new DefaultAcsClient(profile);
            final AssumeRoleRequest request = new AssumeRoleRequest();
            // 适用于Java SDK 3.12.0及以上版本。
            request.setSysMethod(MethodType.POST);
            // 适用于Java SDK 3.12.0以下版本。
            // request.setMethod(MethodType.POST);
            request.setRoleArn(roleArn);
            request.setRoleSessionName(roleSessionName);
            request.setPolicy(policy);
            request.setDurationSeconds(durationSeconds);
            final AssumeRoleResponse response = client.getAcsResponse(request);

            map.put("expiration", response.getCredentials().getExpiration());
            map.put("access_key_id", response.getCredentials().getAccessKeyId());
            map.put("access_key_secret ", response.getCredentials().getAccessKeySecret());
            map.put("security_token", response.getCredentials().getSecurityToken());
            map.put("requestId", response.getRequestId());
            log.info("Expiration: " + response.getCredentials().getExpiration());
            log.info("Access Key Id: " + response.getCredentials().getAccessKeyId());
            log.info("Access Key Secret: " + response.getCredentials().getAccessKeySecret());
            log.info("Security Token: " + response.getCredentials().getSecurityToken());
            log.info("RequestId: " + response.getRequestId());
        } catch (ClientException e) {
            log.info("Failed：");
            log.info("Error code: " + e.getErrCode());
            log.info("Error message: " + e.getErrMsg());
            log.info("RequestId: " + e.getRequestId());
        }
        return map;
    }

}
